package com.car.loan.project.xr.util.bo.business.modify;

import com.alibaba.fastjson.JSON;
import com.car.loan.common.utils.BeanUtils;
import com.car.loan.project.system.domain.SysUser;
import com.car.loan.project.xr.domain.LoanModifyInfo;
import com.car.loan.project.xr.util.vo.modify.LoanModifyDetail;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import lombok.Data;

/**
 * 修改记录
 *
 * @author huangding
 * @date 2020/2/20 22:06
 */
@Data
public class LoanModifyInfoBo {


    @ApiModelProperty("修改时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime modifyTime;

    @ApiModelProperty("修改人员")
    private String modifyAdminName;

    @ApiModelProperty("修改备注")
    private String modifyRemark;

    @ApiModelProperty("修改字段")
    private List<LoanModifyFiledBo> loanModifyFiledBos;


    public static LoanModifyInfoBo transform(LoanModifyInfo loanModifyInfo,
        Map<String, SysUser> sysUserMap) {
        String modifyContent = loanModifyInfo.getModifyContent();
        List<LoanModifyFiledBo> loanModifyFiledBos = JSON
            .parseArray(modifyContent, LoanModifyFiledBo.class);

        LoanModifyInfoBo loanModifyInfoBo = new LoanModifyInfoBo();
        loanModifyInfoBo.setModifyTime(loanModifyInfo.getModifyTime());
        loanModifyInfoBo
            .setModifyAdminName(
                sysUserMap.get(loanModifyInfo.getModifyId().toString()).getUserName());
        loanModifyInfoBo.setModifyRemark(loanModifyInfo.getModifyRemark());
        loanModifyInfoBo.setLoanModifyFiledBos(loanModifyFiledBos);
        return loanModifyInfoBo;
    }


    public static List<LoanModifyFiledBo> getLoanModifyFiledBos(LoanModifyBo dest,
        LoanModifyDetail src) {
        List<Method> destGetters = BeanUtils.getGetterMethods(dest);
        List<Method> srcGetters = BeanUtils.getGetterMethods(src);
        List<LoanModifyFiledBo> loanModifyFiledBos = new ArrayList<>();
        destGetters.forEach(destGetter -> {
            ModifyIgnore modifyIgnore = destGetter.getAnnotation(ModifyIgnore.class);
            if (modifyIgnore != null) {
                return;
            }
            if (BeanUtils.isGetClassMethod(destGetter.getName())) {
                return;
            }
            srcGetters.forEach(srcGetter -> {
                if (BeanUtils.isMethodPropEquals(destGetter.getName(), srcGetter.getName())
                    && destGetter.getReturnType().equals(srcGetter.getReturnType())) {
                    try {
                        Field field = dest.getClass()
                            .getDeclaredField(BeanUtils.getFiledName(destGetter.getName()));
                        ApiModelProperty apiModelProperty = field
                            .getAnnotation(ApiModelProperty.class);
                        String modifyFiledType = apiModelProperty.value();
                        Object destInvoke = destGetter.invoke(dest);
                        Object srcInvoke = srcGetter.invoke(src);
                        if(null != destInvoke){
                            loanModifyFiledBos.addAll(getLoanModifyFiledBos(
                                destInvoke, srcInvoke, modifyFiledType));
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        throw new NullPointerException("对比字段出错:" + e.getMessage());
                    }
                }
            });
        });
        return loanModifyFiledBos;
    }

    /**
     * 获取修改字段
     *
     * @param dest 需要对比的数据
     * @param src 源数据
     */
    public static List<LoanModifyFiledBo> getLoanModifyFiledBos(Object dest, Object src,
        String modifyFiledType) {
        List<Method> destGetters = BeanUtils.getGetterMethods(dest);
        List<Method> srcGetters = BeanUtils.getGetterMethods(src);

        List<LoanModifyFiledBo> loanModifyFiledBos = new ArrayList<>(30);
        try {
            for (Method destGetter : destGetters) {
                ModifyIgnore modifyIgnore = destGetter.getAnnotation(ModifyIgnore.class);
                if (modifyIgnore != null) {
                    continue;
                }
                if (BeanUtils.isGetClassMethod(destGetter.getName())) {
                    continue;
                }
                for (Method srcGetter : srcGetters) {
                    if (BeanUtils.isGetClassMethod(srcGetter.getName())) {
                        continue;
                    }
                    if (BeanUtils.isMethodPropEquals(destGetter.getName(), srcGetter.getName())
                        && destGetter.getReturnType().equals(srcGetter.getReturnType())) {
                        //忽略的字段不记录
                        if (!destGetter.invoke(dest).equals(srcGetter.invoke(src))) {
                            Field field = dest.getClass()
                                .getDeclaredField(BeanUtils.getFiledName(destGetter.getName()));
                            ApiModelProperty apiModelProperty = field
                                .getAnnotation(ApiModelProperty.class);
                            LoanModifyFiledBo loanModifyFiledBo = new LoanModifyFiledBo();
                            loanModifyFiledBo.setModifyFiledType(modifyFiledType);
                            loanModifyFiledBo.setModifyFiledName(apiModelProperty.value());
                            loanModifyFiledBo
                                .setModifyFiledAfterValue(destGetter.invoke(dest).toString());
                            loanModifyFiledBo
                                .setModifyFiledBeforeValue(srcGetter.invoke(src).toString());
                            loanModifyFiledBos.add(loanModifyFiledBo);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new NullPointerException("对比字段出错:" + e.getMessage());
        }
        return loanModifyFiledBos;
    }

}
